﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Perceiveit.Xml
{
    internal class XPropertyAttribute<T> : XPropertySimple<T>
    {

        internal XPropertyAttribute()
            : base()
        {
        }

        public override T GetValue(XEntity entity)
        {
            XPropertyCell<T> tcell;
            T value;
            if (!this.TryGetCell(entity, out tcell))
            {
                XAttribute attr = this.GetAttribute(entity, true);
                value = Converter.FromString(attr.Value);
                tcell = this.RegisterNewCell(entity, attr, value);
            }
            else if (this.Volatile)
            {
                XAttribute attr = tcell.Node as XAttribute;
                value = this.Converter.FromString(attr.Value);
            }
            else
                value = tcell.Value;

            return value;
        }

        public override void SetValue(XEntity entity, T value)
        {
            XPropertyCell<T> tcell;
            if (this.TryGetCell(entity, out tcell))
            {
                XAttribute attr = tcell.Node as XAttribute;
                attr.Value = Converter.ToString(value);
                tcell.Value = value;
            }
            else
            {
                XAttribute attr = this.GetAttribute(entity, true);
                tcell = new XPropertyCell<T>(value, attr);
                attr.Value = Converter.ToString(value);
            }
        }

        public override void ClearValue(XEntity entity)
        {
            XPropertyCell<T> tcell;
            XAttribute attr;

            //TODO: ClearValue() can be improved to remove and return the cell in one action
            if (this.TryGetCell(entity, out tcell))
            {
                attr = tcell.Node as XAttribute;
                attr.Remove();
                entity.ClearCell(this);
            }
            else
            {
                attr = this.GetAttribute(entity, false);
                if (null != attr)
                    attr.Remove();
            }
        }

        
    }
}
